/******************************************************************************
 * profile.c
 * 
 * Main source file for fast tracking of profiling events. The functions
 * defined here are called via macros in profile.h.
 * 
 * Copyright (c) 1999-2000, K A Fraser.
 */

#include "profile.h"

#include "defines.h"
#ifdef USE_PTH
#include <pth.h>
#endif

#include <stdio.h>
#include <stdlib.h>

#define PROF_BUF_ENTRIES 10000

typedef unsigned int u32;

static FILE *fp = NULL;
static u32 *__prof_buf;
u32 *__prof;
u32 *__prof_end;

/******************************************************************************
 * prof_init:
 *   Initialise profiling.
 */
void prof_init(void)
{
    if ( (fp = fopen("/local/scratch/kaf24/out.prof", "wb")) == NULL )
    {
        fprintf(stderr, "Couldn't open profile fp -- going for /dev/null\n");
        if ( (fp = fopen("/dev/null", "wb")) == NULL )
        {
            fprintf(stderr, "Couldn't get /dev/null either!\n");
            exit(1);
        }
    }

    if ( (__prof_buf = malloc(PROF_BUF_ENTRIES*3*sizeof(u32))) == NULL )
    {
        fprintf(stderr, "Couldn't allocate profile buffer\n");
        fclose(fp);
        fp = 0;
    }

    __prof = __prof_buf;
    __prof_end = __prof_buf + 3*PROF_BUF_ENTRIES;
}


/******************************************************************************
 * prof_close:
 *   Close down profiling.
 */
void prof_close(void)
{
    if ( fp )
    {
        fclose(fp);
        fp = NULL;
    }

    if ( __prof_buf != NULL )
    {
        free(__prof_buf);
        __prof_buf = NULL;
    }
}


/******************************************************************************
 * flush_prof_buffer:
 *   Flush the contents of the profile buffer to backing store, resetting
 *   the in-memory buffer.
 */
void flush_prof_buffer(void)
{
    fwrite(__prof_buf, 1, (__prof - __prof_buf) * sizeof(u32), fp);
    __prof = __prof_buf;
}
